package org.fengling.readingplatform.user.service.Impl;

import jakarta.annotation.Resource;
import org.fengling.readingplatform.user.service.UserService;
import org.fengling.readingplatform.utils.AuthContextUtil;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    // 会员签到的方式
    @Override
    public void sign() {
        // 1.获取当前登录用户
        Long userId = AuthContextUtil.getUserInfo().getId();
        System.out.println(userId);
        // 2. 获取日期
        LocalDateTime now = LocalDateTime.now();
        // 3. 拼接key
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key = "sign:" + userId + keySuffix;
        // 4. 获取今天是本月的第几天
        int dayOfMonth = now.getDayOfMonth();
        // 5. 写入Redis SETBIT key offset 1
        stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);
    }

    @Override
    public int signCount() {
        // 1.获取当前登录用户
        Long userId = AuthContextUtil.getUserInfo().getId();
        System.out.println(userId);
        // 2. 获取日期
        LocalDateTime now = LocalDateTime.now();
        // 3. 拼接key
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key = "sign:" + userId + keySuffix;
        // 4. 获取今天是本月的第几天
        int dayOfMonth = now.getDayOfMonth();
        // 5. 获取本月截止今天为止的所有的签到记录，返回的是一个十进制的数字
        List<Long> result = stringRedisTemplate.opsForValue().bitField(
                key, BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0)
        );
        if(result == null || result.isEmpty()){
            System.out.println("ggggg");
            // 没有任何签到结果
            return 0;
        }

        Long num = result.get(0);
        if(num == null || num == 0){
            return 0;
        }
        int count = 0;
        // 6. 循环遍历
        // 如果为0，说明未签到，结束
        // 如果不为0，说明已签到，计数器+1
        while ((num & 1) != 0) {
            // 6.1. 让这个数字与1做与运算，得到数字的最后一个bit位,判断这个bit位是否为0
            count++;
            num >>>= 1;
            // 把数字右移一位，抛弃最后一个bit位，继续下一个bit位
        }
    return count;
    }
}